package com.meizhao.admin.interceptor;

import com.meizhao.admin.annotation.NoRepeatRequest;
import com.meizhao.admin.entity.dto.request.ReqDto;
import com.meizhao.admin.exception.CommonException;
import com.meizhao.admin.service.RedisService;
import com.meizhao.admin.utils.HttpUtils;
import com.meizhao.admin.utils.OtherUtils;
import com.meizhao.admin.utils.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;


@Slf4j
@Aspect
@Component
public class RepeatRequestAspect {

    @Autowired
    private RedisService<String, String> redisService;

    @Pointcut("@annotation(noRepeatRequest)")
    public void pointCut(NoRepeatRequest noRepeatRequest) {}

    @Around("pointCut(noRepeatRequest)")
    public Object around(ProceedingJoinPoint pjp, NoRepeatRequest noRepeatRequest) throws Throwable {

        StringBuilder builder = new StringBuilder();
        final Object[] args = pjp.getArgs();
        for(int i=0;i<args.length;i++){
            if(args[i] instanceof ReqDto){
                builder.append(args[i]);
            }
        }

        String lockKey = "nocache:"+ HttpUtils.getTokenByRequest()+":"+HttpUtils.getRequest().getServletPath()+":"+ OtherUtils.getMD5(builder.toString());
        String value = redisService.getAndSet(lockKey,"2");
        redisService.expire(lockKey,noRepeatRequest.expire(), TimeUnit.SECONDS);
        if("2".equals(value)){
            throw new CommonException(ResultCode.EXCEPTION, "重复提交");
        }
        try {
            return pjp.proceed();
        } catch (Throwable throwable) {
            throw throwable;
        }
    }
}
